#include <iostream>
#include <memory>

int main()
{
    // 智能指针的初始化
    std::shared_ptr<int> p(new int(1));
    std::shared_ptr<int> p2 = p;
    std::shared_ptr<int> ptr;
    // reset发生了啥？
    // 1. 如果ptr是空指针，则ptr指向new int(1)
    // 2. 如果ptr不是空指针，则ptr指向new int(1)，并且原来的对象的引用计数减1
    ptr.reset(new int(1));
    // ptr释放
    ptr.reset();
    // 打印计数
    std::cout << "ptr's reference count: " << ptr.use_count() << std::endl;

    // 打印p2的引用计数
    std::cout << "p2's reference count: " << p2.use_count() << std::endl;
    p2.reset(new int(2));
    // 打印reset后的引用计数
    std::cout << "ptr's reference count after reset: " << ptr.use_count() << std::endl;

    // 给shared_ptr自定义删除器
    std::shared_ptr<int> p3(new int(3), [](int *p)
                            { std::cout << "delete int" << std::endl; delete p; });
    // 打印p3的引用计数
    std::cout << "p3's reference count: " << p3.use_count() << std::endl;
    if (ptr)
    {
        std::cout << "ptr is not null";
    }

    //
    // shared_ptr自定义删除器
    std::shared_ptr<int> ptr_uni(new int(10), [](int *p)
                                 {
                                 delete p;
                                 // 打印
                                 std::cout << "delete shared_ptr int" << std::endl; });

    // 将删除器作为类型的一部分主要是为了性能和编译期优化。这种设计使得删除器可以在编译时内联，避免运行时额外的函数调用开销。
    // 对于shared_ptr，删除器是运行时绑定的，会有轻微的性能损失
    //  unique_ptr自定义删除器
    std::unique_ptr<int, void (*)(int *)> ptr_shared(new int(10), [](int *p)
                                                     {
                                                  delete p;
                                                  // 打印
                                                  std::cout << "delete unique_ptr int" << std::endl; });

    // shared_ptr的坑

    return 0;
}